home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 March / Macworld (1998-03) (Disk 1).dmg / Shareware World / Info / For Developers / GhostScript 5.10 / MacGS-510 / files / gs_res.ps < prev    next >
Text File  |  1997-07-07  |  19KB  |  666 lines

  1. %    Copyright (C) 1994, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % Initialization file for Level 2 resource machinery.
  16. % When this is run, systemdict is still writable,
  17. % but (almost) everything defined here goes into level2dict.
  18.  
  19. level2dict begin
  20.  
  21. (BEGIN RESOURCES) VMDEBUG
  22.  
  23. % We keep track of (global) instances with another entry in the resource
  24. % dictionary, an Instances dictionary.  For categories with implicit
  25. % instances, the values in Instances are the same as the keys;
  26. % for other categories, the values are [instance status size].
  27.  
  28. % Note that the dictionary that defines a resource category is stored
  29. % in global memory.  The PostScript manual says that each category must
  30. % manage global and local instances separately.  However, objects in
  31. % global memory other than systemdict can't reference objects in local memory.
  32. % This means that the resource category dictionary, which would otherwise be
  33. % the obvious place to keep track of the instances, can't be used to keep
  34. % track of local instances.  Instead, we define a dictionary in local VM
  35. % called localinstancedict, in which the key is the category name and
  36. % the value is the analogue of Instances for local instances.
  37.  
  38. % We don't currently implement automatic resource unloading.
  39. % When and if we do, it should be hooked to the garbage collector.
  40. % However, Ed Taft of Adobe says their interpreters don't implement this
  41. % either, so we aren't going to worry about it for a while.
  42.  
  43. currentglobal false setglobal systemdict begin
  44.   /localinstancedict 5 dict def
  45. end true setglobal
  46. /.emptydict 0 dict readonly def
  47. setglobal
  48.  
  49. % Resource category dictionaries have the following keys (those marked with
  50. % * are optional):
  51. %    Standard, defined in the Red Book:
  52. %        Category (name)
  53. %        *InstanceType (name)
  54. %        DefineResource
  55. %            <key> <instance> DefineResource <instance>
  56. %        UndefineResource
  57. %            <key> UndefineResource -
  58. %        FindResource
  59. %            <key> FindResource <instance>
  60. %        ResourceStatus
  61. %            <key> ResourceStatus <status> <size> true
  62. %            <key> ResourceStatus false
  63. %        ResourceForAll
  64. %            <template> <proc> <scratch> ResourceForAll -
  65. %        *ResourceFileName
  66. %            <key> <scratch> ResourceFileName <filename>
  67. %    Additional, specific to our implementation:
  68. %        Instances (dictionary)
  69. %        .LocalInstances
  70. %            - .LocalInstances <dict>
  71. %        .GetInstance
  72. %            <key> .GetInstance <instance> -true-
  73. %            <key> .GetInstance -false-
  74. %        .CheckResource
  75. %            <key> <value> .CheckResource <key> <value> <ok>
  76. %              (or may give an error if not OK)
  77. %        .DoLoadResource
  78. %            <key> .DoLoadResource - (may give an error)
  79. %        .LoadResource
  80. %            <key> .LoadResource - (may give an error)
  81. %        .ResourceFile
  82. %            <key> .ResourceFile <file> -true-
  83. %            <key> .ResourceFile <key> -false-
  84. % All the above procedures expect that the top dictionary on the d-stack
  85. % is the resource dictionary.
  86.  
  87. % Define enough of the Category category so we can define other categories.
  88. % The dictionary we're about to create will become the Category
  89. % category definition dictionary.
  90.  
  91. /.findcategory        % <name> .findcategory <category>
  92.  { { /Category findresource } stopped { pop stop } if
  93.  } bind def
  94.  
  95. /.resourceexec        % <key> /xxxResource .resourceexec -
  96.  {            %   (also pops the category from the dstack)
  97.    load stopped { Category end stop } if end
  98.  } bind def
  99.  
  100. 12 dict begin
  101.  
  102.         % Standard entries
  103.  
  104. /Category /Category def
  105. /InstanceType /dicttype def
  106.  
  107. /DefineResource
  108.     { .CheckResource
  109.        { dup /Category 3 index cvlit .growput
  110.         % We would like to make Category dictionaries read-only,
  111.         % and we used to do that here, but we can't do it,
  112.         % because we have to be able to replace the dummy, empty
  113.         % Instances dictionary with the real one later.
  114.          dup [ exch 0 -1 ] exch
  115.          Instances 4 2 roll put
  116.        }
  117.        { /defineresource load /typecheck signalerror
  118.        }
  119.       ifelse
  120.     } bind def
  121. /FindResource        % (redefined below)
  122.     { Instances exch get 0 get
  123.     } bind def
  124.  
  125.         % Additional entries
  126.  
  127. /Instances 25 dict def
  128. Instances /Category [currentdict 0 -1] put
  129.  
  130. /.LocalInstances 0 dict def
  131. /.GetInstance
  132.     { Instances exch .knownget
  133.     } bind def
  134. /.CheckResource
  135.     { dup gcheck currentglobal and
  136.        { /DefineResource /FindResource /ResourceForAll /ResourceStatus
  137.          /UndefineResource }
  138.        { 2 index exch known and }
  139.       forall
  140.       not { /defineresource load /invalidaccess signalerror } if
  141.       true
  142.     } bind def
  143.  
  144. Instances end begin    % for the base case of findresource
  145.  
  146. (END CATEGORY) VMDEBUG
  147.  
  148. % Define the resource operators.  We use the "stack protection" feature of
  149. % odef to make sure the stacks are restored properly on an error.
  150. % This requires that the operators not pop anything from the stack until
  151. % they have executed their logic successfully.  We can't make this
  152. % work for resourceforall, but we can make it work for the others.
  153.  
  154. mark
  155. /defineresource {    % <key> <instance> <category> defineresource <instance>
  156.     3 copy .findcategory dup begin
  157.     /InstanceType known {
  158.       dup type InstanceType ne {
  159.         dup type /packedarraytype eq InstanceType /arraytype eq and
  160.         not { /defineresource load /typecheck signalerror } if
  161.       } if
  162.     } if
  163.     /DefineResource .resourceexec
  164.     4 1 roll pop pop pop
  165. }
  166. /findresource {        % <key> <category> findresource <instance>
  167.     2 copy dup /Category eq
  168.       { pop //Category 0 get } { .findcategory } ifelse
  169.     begin
  170.     /FindResource .resourceexec exch pop exch pop
  171. }
  172. /resourceforall {    % <template> <proc> <scratch> <category> resourceforall -
  173.     .findcategory begin /ResourceForAll .resourceexec
  174. }
  175. /resourcestatus {    % <key> <category> resourcestatus <status> <size> true
  176.             % <key> <category> resourcestatus false
  177.     2 copy .findcategory begin /ResourceStatus .resourceexec
  178.      { 4 2 roll pop pop true } { pop pop false } ifelse
  179. }
  180. /undefineresource {    % <key> <category> undefineresource -
  181.     2 copy .findcategory begin /UndefineResource .resourceexec pop pop
  182. }
  183. end        % Instances of Category
  184. counttomark 2 idiv { bind odef } repeat pop
  185.  
  186. % Define the system parameters used for the Generic implementation of
  187. % ResourceFileName.
  188. systemdict begin
  189. currentdict /systemparams known not { /systemparams 10 dict readonly def } if
  190. systemparams
  191.   dup /FontResourceDir (/Resource/Font/) readonly .forceput
  192.   dup /GenericResourceDir (/Resource/) readonly .forceput
  193.   dup /GenericResourcePathSep (/) readonly .forceput
  194. pop
  195. end
  196.  
  197. % Define the generic algorithm for computing resource file names.
  198. /.rfnstring 100 string def
  199. /.genericrfn        % <key> <scratch> <prefix> .genericrfn <filename>
  200.  { 3 -1 roll //.rfnstring cvs concatstrings exch copy
  201.  } bind def
  202.  
  203. % Define the Generic category.
  204.  
  205. /Generic mark
  206.  
  207.         % Standard entries
  208.  
  209. % We're still running in Level 1 mode, so dictionaries won't expand.
  210. % Leave room for the /Category entry.
  211. /Category null
  212.  
  213. /DefineResource
  214.     { .CheckResource
  215.        { dup [ exch 0 -1 ]
  216.             % Stack: key value instance
  217.          currentglobal
  218.           { false setglobal 2 index UndefineResource    % remove local def if any
  219.         true setglobal
  220.         Instances dup //.emptydict eq
  221.          { pop 3 dict /Instances 1 index def
  222.          }
  223.         if
  224.           }
  225.           { .LocalInstances dup //.emptydict eq
  226.              { pop 3 dict localinstancedict Category 2 index put
  227.          }
  228.         if
  229.           }
  230.          ifelse
  231.             % Stack: key value instance instancedict
  232.          3 index 2 index .growput
  233.             % Now make the resource value read-only.
  234.          0 2 copy get { readonly } .internalstopped pop
  235.          dup 4 1 roll put exch pop exch pop
  236.        }
  237.        { /defineresource load /typecheck signalerror
  238.        }
  239.       ifelse
  240.     } bind
  241. /UndefineResource
  242.     {  { dup 2 index .knownget
  243.           { dup 1 get 1 ge
  244.          { dup 0 null put 1 2 put pop pop }
  245.          { pop exch .undef }
  246.         ifelse
  247.           }
  248.           { pop pop
  249.           }
  250.          ifelse
  251.        }
  252.       currentglobal
  253.        { 2 copy Instances exch exec
  254.        }
  255.       if .LocalInstances exch exec
  256.     } bind
  257. /FindResource
  258.     { dup ResourceStatus
  259.        { pop 1 gt            % not in VM
  260.           { .DoLoadResource
  261.           }
  262.          if
  263.          .GetInstance pop        % can't fail
  264.          0 get
  265.        }
  266.        { /findresource load /undefinedresource signalerror
  267.        }
  268.       ifelse
  269.     } bind
  270. /ResourceStatus
  271.     { dup .GetInstance
  272.        { exch pop dup 1 get exch 2 get true }
  273.        { .ResourceFile
  274.           { closefile 2 -1 true }
  275.           { pop false }
  276.          ifelse
  277.        }
  278.       ifelse
  279.     } bind
  280. /ResourceForAll
  281.     { % **************** Doesn't present instance groups in
  282.       % **************** the correct order yet.
  283.       % We construct a new procedure so we don't have to use
  284.       % static resources to hold the iteration state.
  285.       % Make sure it is in local VM, to avoid an invalidaccess.
  286.       3 copy .currentglobal 4 1 roll false .setglobal
  287.       3 packedarray        % template, proc, scratch
  288.       { exch pop    % stack contains: key, {template, proc, scratch}
  289.         2 copy 0 get .stringmatch
  290.          { 1 index type dup /stringtype eq exch /nametype eq or
  291.         { 2 copy 2 get cvs
  292.           exch 1 get 3 -1 roll pop
  293.         }
  294.         { 1 get
  295.         }
  296.            ifelse exec
  297.          }
  298.          { pop pop
  299.          }
  300.         ifelse
  301.       } /exec cvx 3 packedarray cvx
  302.       % Stack: template proc scratch global? iterproc
  303.       % We must pop the resource dictionary off the dict stack
  304.       % when doing the actual iteration, and restore it afterwards.
  305.       currentglobal .LocalInstances length 0 eq or not
  306.        {        % We must do local instances, and do them first.
  307.          /forall cvx 1 index currentdict 3 packedarray cvx
  308.          .LocalInstances 3 1 roll end exec begin
  309.        }
  310.       if
  311.       exch .setglobal
  312.       Instances exch
  313.       /forall cvx currentdict
  314.       end 2 .execn begin pop pop pop
  315.     } bind
  316. /ResourceFileName
  317.     { /GenericResourceDir getsystemparam 
  318.       Category .namestring concatstrings
  319.       /GenericResourcePathSep getsystemparam concatstrings
  320.       .genericrfn
  321.     } bind
  322.  
  323.         % Additional entries
  324.  
  325. % Unfortunately, we can't create the real Instances dictionary now,
  326. % because if someone copies the Generic category (which pp. 95-96 of the
  327. % 2nd Edition Red Book says is legitimate), they'll wind up sharing
  328. % the Instances.  Instead, we have to create Instances on demand,
  329. % just like the entry in localinstancedict.
  330. % We also have to prevent anyone from creating instances of Generic itself.
  331. /Instances //.emptydict
  332.  
  333. /.LocalInstances
  334.     { localinstancedict Category .knownget not { //.emptydict } if
  335.     } bind
  336. /.GetInstance
  337.     { currentglobal
  338.        { Instances exch .knownget }
  339.        { .LocalInstances 1 index .knownget
  340.           { exch pop true }
  341.           { Instances exch .knownget }
  342.          ifelse
  343.        }
  344.       ifelse
  345.     } bind
  346. /.CheckResource
  347.     { true
  348.     } bind
  349. /.DoLoadResource
  350.     { dup vmstatus pop exch pop exch
  351.       .LoadResource
  352.       vmstatus pop exch pop exch sub
  353.       1 index .GetInstance not
  354.        { pop dup /undefinedresource signalerror }    % didn't load
  355.       if
  356.       dup 1 1 put
  357.       2 3 -1 roll put
  358.     } bind
  359. /.LoadResource
  360.     { dup .ResourceFile
  361.        { exch pop currentglobal
  362.           { run }
  363.           { true setglobal { run } stopped false setglobal { stop } if }
  364.          ifelse
  365.        }
  366.        { dup /undefinedresource signalerror
  367.        }
  368.      ifelse
  369.     } bind
  370. /.ResourceFile
  371.     { currentdict /ResourceFileName known
  372.        { mark 1 index 100 string { ResourceFileName }
  373.          .internalstopped
  374.           { cleartomark false }
  375.           { exch pop findlibfile
  376.          { exch pop exch pop true }
  377.          { pop false }
  378.         ifelse
  379.           }
  380.          ifelse
  381.        }
  382.        { false }
  383.       ifelse
  384.     } bind
  385.  
  386. .dicttomark
  387. /Category defineresource pop
  388.  
  389. % Fill in the rest of the Category category.
  390. /Category /Category findresource dup
  391. /Generic /Category findresource begin
  392.  { /FindResource /ResourceForAll /ResourceStatus /UndefineResource /.ResourceFile }
  393.  { dup load put dup } forall
  394. pop readonly pop end
  395.  
  396. (END GENERIC) VMDEBUG
  397.  
  398. % Define the fixed categories.
  399.  
  400. mark
  401.     % Things other than types
  402.  /ColorSpaceFamily
  403.    mark colorspacedict { pop } forall .packtomark
  404.  /Emulator
  405.    mark EMULATORS { cvn } forall .packtomark
  406.  /Filter
  407.    mark filterdict { pop } forall .packtomark
  408.  /IODevice
  409.     % Loop until the .getiodevice gets a rangecheck.
  410.    errordict /rangecheck 2 copy get
  411.    errordict /rangecheck { pop stop } put    % pop the command
  412.    mark 0 { {dup .getiodevice exch 1 add} loop} .internalstopped
  413.    pop pop pop .packtomark
  414.    4 1 roll put
  415.    .clearerror
  416.     % Types
  417.  /setcolorrendering where
  418.   { pop /ColorRenderingType
  419.      {1}
  420.   } if
  421.  /FMapType
  422.    { }    % These must be deferred, because optional features may add some.
  423.  /FontType
  424.    { }    % These must be deferred, because optional features may add some.
  425.  /FormType
  426.    {1}
  427.  /HalftoneType
  428.    {1 2 3 4 5}
  429.  /ImageType
  430.    {1}
  431.  /PatternType
  432.    {1}            % should check for Pattern color space
  433. counttomark 2 idiv
  434.  { mark
  435.  
  436.         % Standard entries
  437.  
  438.         % We'd like to prohibit defineresource,
  439.         % but because optional features may add entries, we can't.
  440.         % We can at least require that the key and value match.
  441.    /DefineResource
  442.     { currentglobal not
  443.        { /defineresource load /invalidaccess signalerror }
  444.        { 2 copy ne
  445.           { /defineresource load /rangecheck signalerror }
  446.           { dup Instances 4 -2 roll .growput }
  447.          ifelse
  448.        }
  449.       ifelse
  450.     } bind
  451.    /UndefineResource
  452.     { /undefineresource load /invalidaccess signalerror } bind
  453.    /FindResource
  454.     { Instances 1 index .knownget
  455.        { exch pop }
  456.        { /findresource load /undefinedresource signalerror }
  457.       ifelse
  458.     } bind
  459.    /ResourceStatus
  460.     { Instances exch known { 0 0 true } { false } ifelse } bind
  461.    /ResourceForAll
  462.     /Generic /Category findresource /ResourceForAll get
  463.  
  464.         % Additional entries
  465.  
  466.    counttomark 2 add -1 roll
  467.    dup length dict dup begin exch { dup def } forall end
  468.         % We'd like to make the Instances readonly here,
  469.         % but because optional features may add entries, we can't.
  470.    /Instances exch
  471.    /.LocalInstances    % used by ResourceForAll
  472.     0 dict def
  473.  
  474.    .dicttomark /Category defineresource pop
  475.  } repeat pop
  476.  
  477. (END FIXED) VMDEBUG
  478.  
  479. % Define the other built-in categories.
  480.  
  481. /.definecategory    % <name> -mark- <key1> ... <valuen> .definecategory -
  482.  { counttomark 2 idiv 2 add        % Instances, Category
  483.    /Generic /Category findresource dup maxlength 3 -1 roll add
  484.    dict .copydict begin
  485.    counttomark 2 idiv { def } repeat pop    % pop the mark
  486.    currentdict end /Category defineresource pop
  487.  } bind def
  488.  
  489. /ColorRendering mark /InstanceType /dicttype .definecategory
  490. /ColorSpace mark /InstanceType /arraytype .definecategory
  491. /Form mark /InstanceType /dicttype .definecategory
  492. /Halftone mark /InstanceType /dicttype .definecategory
  493. /Pattern mark /InstanceType /dicttype .definecategory
  494. /ProcSet mark /InstanceType /dicttype .definecategory
  495.  
  496. (END MISC) VMDEBUG
  497.  
  498. % Define the Encoding category.
  499.  
  500. /Encoding mark
  501.  
  502. /InstanceType /arraytype
  503.  
  504. % Handle already-registered encodings, including lazily loaded encodings
  505. % that aren't loaded yet.
  506.  
  507. /Instances mark
  508.   EncodingDirectory
  509.    { dup length 256 eq { [ exch readonly 0 -1 ] } { pop [null 2 -1] } ifelse
  510.    } forall
  511. .dicttomark
  512.  
  513. /.ResourceFileDict mark
  514.   EncodingDirectory
  515.    { dup length 256 eq { pop pop } { 0 get } ifelse
  516.    } forall
  517. .dicttomark
  518.  
  519. /ResourceFileName
  520.  { .ResourceFileDict 2 index .knownget
  521.     { exch copy exch pop }
  522.     { /Generic /Category findresource /ResourceFileName get exec }
  523.    ifelse
  524.  } bind
  525.  
  526. .definecategory            % Encoding
  527.  
  528. % Make placeholders in level2dict for the redefined Encoding operators,
  529. % so that they will be swapped properly when we switch language levels.
  530.  
  531. /.findencoding /.findencoding load def
  532. /findencoding /findencoding load def
  533. /.defineencoding /.defineencoding load def
  534.  
  535. (END ENCODING) VMDEBUG
  536.  
  537. % Define the Font category.
  538.  
  539. /Font mark
  540.  
  541. /InstanceType /dicttype
  542.  
  543. /DefineResource
  544.     { 2 copy //definefont exch pop
  545.       /Generic /Category findresource /DefineResource get exec
  546.     } bind
  547. /UndefineResource
  548.     { dup //undefinefont
  549.       /Generic /Category findresource /UndefineResource get exec
  550.     } bind
  551. /FindResource
  552.     { dup ResourceStatus
  553.        { pop 1 gt { .loadfont } { .GetInstance pop 0 get } ifelse }
  554.        { .loadfont }
  555.       ifelse
  556.     } bind
  557. /ResourceFileName
  558.     { /FontResourceDir getsystemparam .genericrfn
  559.     } bind
  560.  
  561. /.loadfont
  562.     { dup vmstatus pop exch pop exch
  563.       //findfont exec exch        % findfont is a procedure....
  564.       vmstatus pop exch pop exch sub
  565.         % stack: name font vmused
  566.         % findfont has the prerogative of not calling definefont
  567.         % in certain obscure cases of font substitution.
  568.       2 index .GetInstance
  569.        { dup 1 1 put
  570.          2 3 -1 roll put
  571.        }
  572.        { pop
  573.        }
  574.       ifelse exch pop
  575.     } bind
  576.  
  577. /Instances FontDirectory length 2 mul dict
  578.  
  579. .definecategory            % Font
  580.  
  581. % Redefine font "operators".
  582. /.definefontmap
  583.  { /Font /Category findresource /Instances get
  584.    dup 3 index known
  585.     { pop
  586.     }
  587.     { 2 index
  588.         % Make sure we create the array in global VM.
  589.       .currentglobal true .setglobal
  590.       [null 2 -1] exch .setglobal
  591.       .growput
  592.     }
  593.    ifelse
  594.    //.definefontmap exec
  595.  } bind def
  596.  
  597. % Make sure the old definitions are still in systemdict so that
  598. % they will get bound properly.
  599. systemdict begin
  600.   /.origdefinefont /definefont load def
  601.   /.origundefinefont /undefinefont load def
  602.   /.origfindfont /findfont load def
  603. end
  604. /definefont {
  605.   /Font defineresource
  606. } bind odef
  607. /undefinefont {
  608.   /Font undefineresource
  609. } bind odef
  610. % The Red Book requires that findfont be a procedure, not an operator,
  611. % but it still needs to restore the stacks reliably if it fails.
  612. /.findfontop {
  613.   /Font findresource
  614. } bind odef
  615. /findfont {
  616.   .findfontop
  617. } bind def    % Must be a procedure, not an operator
  618.  
  619. % Remove initialization utilities.
  620. currentdict /.definecategory .undef
  621. currentdict /.emptydict .undef
  622.  
  623. end                % level2dict
  624.  
  625. % Convert deferred resources after we finally switch to Level 2.
  626.  
  627. /.fixresources {
  628.     % Encoding resources
  629.  EncodingDirectory
  630.    { dup length 256 eq
  631.       { /Encoding defineresource pop }
  632.       { pop pop }
  633.      ifelse
  634.    } forall
  635.   /.findencoding { /Encoding findresource } bind def
  636.   /findencoding /.findencoding load odef
  637.   /.defineencoding { /Encoding defineresource pop } bind def
  638.     % ColorRendering resources and ProcSet
  639.   systemdict /ColorRendering .knownget {
  640.     /ColorRendering exch /ProcSet defineresource pop
  641.     systemdict /ColorRendering undef
  642.     /DefaultColorRendering currentcolorrendering /ColorRendering
  643.       defineresource pop
  644.     % FontType and FMapType resources
  645.   buildfontdict { pop dup /FontType defineresource pop } forall
  646.   mark
  647.     buildfontdict 0 known { 2 3 4 5 6 7 8 } if
  648.     buildfontdict 9 known { 9 } if
  649.   counttomark { dup /FMapType defineresource pop } repeat pop
  650.   } if
  651.     % Make the fixed resource categories immutable.
  652.   { /ColorSpaceFamily /Emulator /Filter /IODevice /ColorRenderingType
  653.     /FMapType /FontType /FormType /HalftoneType /ImageType /PatternType
  654.   } {
  655.     /Category findresource
  656.     dup /Instances get readonly pop
  657.     .LocalInstances readonly pop
  658.     readonly pop
  659.   } forall
  660.     % clean up
  661.   systemdict /.fixresources undef
  662. } bind def
  663.